---
id: lint
slug: /versioned/lint
title: Verifying migration safety
---

import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';

With the `atlas migrate lint` command, users can analyze the migration directory
to detect potentially dangerous changes to the database schema. This command may be
incorporated in _continuous integration_ pipelines to enable teams to enforce desired
policies with regard to schema changes. 

[Learn more about Atlas's analyzers](/lint/analyzers)

### Flags

When using `migrate lint` to analyze migrations, users must supply multiple parameters:
* `--dev-url` a [URL](/concepts/url) to a [Dev-database](/concepts/dev-database) that will be used
 to simulate the changes and verify their correctness.
* `--dir` the URL of the migration directory, by default it is `file://migrations`, e.g a
 directory named `migrations` in the current working directory.

### Changeset detection

When we run the `lint` command, we need to instruct Atlas on how to decide what 
set of migration files to analyze. Currently, two modes are supported.

* `--git-base <branchName>`: which selects the diff between the provided branch and 
 the current one as the changeset.
* `--latest <n>` which selects the latest n migration files as the changeset.

### `nolint` directive

Annotating a statement with the `--atlas:nolint` directive allows excluding it from the analysis reporting. For example:

<Tabs
defaultValue="all-changes"
values={[
{label: 'All changes', value: 'all-changes'},
{label: 'Class of changes', value: 'by-name'},
{label: 'Specific checks', value: 'by-check'},
{label: 'File level', value: 'file-level'},
]}>
<TabItem value="all-changes">

Using `--atlas:nolint` excludes the annotated statement from all linters.

```sql
//highlight-next-line
-- atlas:nolint
ALTER TABLE `t1` DROP COLUMN `c1`, ADD COLUMN `d1` varchar(255) NOT NULL;

//highlight-next-line
--atlas:nolint
ALTER TABLE `t2` DROP COLUMN `c2`, ADD COLUMN `d2` varchar(255) NOT NULL;

//highlight-next-line
/*atlas:nolint*/
ALTER TABLE `t3` DROP COLUMN `c3`, ADD COLUMN `d3` varchar(255) NOT NULL;

//highlight-next-line
#atlas:nolint
ALTER TABLE `t4` DROP COLUMN `c4`, ADD COLUMN `d4` varchar(255) NOT NULL;
```

</TabItem>
<TabItem value="by-name">

Using `--atlas:nolint [names...]` excludes reporting specific analyzers for the annotated statements.

```sql
//highlight-next-line
-- Ignore reporting destructive changes.
//highlight-next-line
-- atlas:nolint destructive
ALTER TABLE `t1` DROP COLUMN `c1`, ADD COLUMN `d1` varchar(255) NOT NULL;

//highlight-next-line
-- Ignore reporting destructive and data-dependent changes.
//highlight-next-line
--atlas:nolint destructive data_depend
ALTER TABLE `t2` DROP COLUMN `c2`, ADD COLUMN `d2` varchar(255) NOT NULL;

//highlight-next-line
/*atlas:nolint data_depend*/
ALTER TABLE `t3` DROP COLUMN `c3`, ADD COLUMN `d3` varchar(255) NOT NULL;

//highlight-next-line
#atlas:nolint destructive data_depend
ALTER TABLE `t4` DROP COLUMN `c4`, ADD COLUMN `d4` varchar(255) NOT NULL;
```

</TabItem>

<TabItem value="by-check">

Using `--atlas:nolint [checks...]` excludes reporting specific [checks](../lint/analyzers.mdx#checks) for the annotated
statement.

```sql
//highlight-next-line
-- atlas:nolint DS103 MY101
ALTER TABLE `t1` DROP COLUMN `c1`, ADD COLUMN `d1` varchar(255) NOT NULL;
```

</TabItem>


<TabItem value="file-level">

The `--atlas:nolint` directive can be used to exclude the whole file (given at top) from analysis, or to exclude specific
statements in the file from specific [checks](../lint/analyzers.mdx#checks) or analyzers.

```sql
//highlight-next-line
-- atlas:nolint

ALTER TABLE `t1` DROP COLUMN `c1`, ADD COLUMN `d1` varchar(255) NOT NULL;

DROP TABLE `t2`;
```

Skip a specific analyzer for all statements in the file:

```sql
//highlight-next-line
-- atlas:nolint destructive

ALTER TABLE `t1` DROP COLUMN `c1`, ADD COLUMN `d1` varchar(255) NOT NULL;

DROP TABLE `t2`;
```

:::note
File directives are located at the top of the file and should not be associated with any statement. Hence, double new
lines are used to separate file directives from its content.
:::

</TabItem>
</Tabs>

### Output

Users may supply a [Go template](https://pkg.go.dev/text/template) string as the `--format` parameter to
format the output of the `lint` command.

### Examples

Analyze the latest migration file using the `docker` driver:

<Tabs>
<TabItem value="MySQL">

```shell
atlas migrate lint \
  --latest 1 \
  --dir "file://migrations" \
  --dev-url "docker://mysql/8/test"
```

</TabItem>
<TabItem value="MariaDB">

```shell
atlas migrate lint \
  --latest 1 \
  --dir "file://migrations" \
  --dev-url "docker://mariadb/latest/test"
```

</TabItem>
<TabItem value="PostgreSQL">

```shell
atlas migrate lint \
  --latest 1 \
  --dir "file://migrations" \
  --dev-url "docker://postgres/15/test?search_path=public"
```

</TabItem>
<TabItem value="SQLite">

```shell
atlas migrate lint \
  --latest 1 \
  --dir "file://migrations" \
  --dev-url "sqlite://file?mode=memory"
```

</TabItem>
</Tabs>

Analyze all changes relative to the `master` Git branch:
```shell
atlas migrate lint \
  --dir "file://my/project/migrations" \
  --dev-url "mysql://root:pass@localhost:3306/dev" \
  --git-base "master"
```

Format output as JSON:
```shell
atlas migrate lint \
  --dir "file://my/project/migrations" \
  --dev-url "mysql://root:pass@localhost:3306/dev" \
  --git-base "master" \
  --format "{{ json .Files }}"
```
Use the configuration defined in [`atlas.hcl`](../atlas-schema/projects#configure-migration-linting):
```shell
atlas migrate lint --env "local"
```

### Reference

[CLI Command Reference](/cli-reference#atlas-migrate-lint)